
#ifndef _GlsxCommon_Exception_H_
#define _GlsxCommon_Exception_H_

#include <stdexcept>
#include "GlsxCommon.h"

BEGIN_GLSX_NAMESPACE


class GlsxCommon_API Exception: public std::exception
{
public:
	Exception(const std::string& msg, int code = 0);

	Exception(const std::string& msg, const std::string& arg, int code = 0);

	Exception(const std::string& msg, const Exception& nested, int code = 0);

	Exception(const Exception& exc);
		
	~Exception() throw();

	Exception& operator = (const Exception& exc);

	virtual const char* name() const throw();
		
	virtual const char* className() const throw();
		
	virtual const char* what() const throw();
		
	const Exception* nested() const;
			
	const std::string& message() const;
			
	int code() const;
		
	std::string displayText() const;

	virtual Exception* clone() const;
		
	virtual void rethrow() const;

protected:
	Exception(int code = 0);

	void message(const std::string& msg);

	void extendedMessage(const std::string& arg);
		
private:
	std::string _msg;
	Exception*  _pNested;
	int			_code;
};

inline const Exception* Exception::nested() const
{
	return _pNested;
}


inline const std::string& Exception::message() const
{
	return _msg;
}


inline void Exception::message(const std::string& msg)
{
	_msg = msg;
}


inline int Exception::code() const
{
	return _code;
}


// #define GLSX_DECLARE_EXCEPTION_CODE(API, CLS, BASE, CODE) \
// 	class API CLS: public BASE														\
// 	{																				\
// 	public:																			\
// 		CLS(int code = CODE);														\
// 		CLS(const std::string& msg, int code = CODE);								\
// 		CLS(const std::string& msg, const std::string& arg, int code = CODE);		\
// 		CLS(const std::string& msg, const Glsx::Exception& exc, int code = CODE);	\
// 		CLS(const CLS& exc);														\
// 		~CLS() throw();																\
// 		CLS& operator = (const CLS& exc);											\
// 		const char* name() const throw();											\
// 		const char* className() const throw();										\
// 		Glsx::Exception* clone() const;												\
// 		void rethrow() const;														\
// 	};
// 
// #define GLSX_DECLARE_EXCEPTION(API, CLS, BASE) \
// 	GLSX_DECLARE_EXCEPTION_CODE(API, CLS, BASE, 0)
// 
// #define Glsx_IMPLEMENT_EXCEPTION(CLS, BASE, NAME)													\
// 	CLS::CLS(int code): BASE(code)																	\
// 	{																								\
// 	}																								\
// 	CLS::CLS(const std::string& msg, int code): BASE(msg, code)										\
// 	{																								\
// 	}																								\
// 	CLS::CLS(const std::string& msg, const std::string& arg, int code): BASE(msg, arg, code)		\
// 	{																								\
// 	}																								\
// 	CLS::CLS(const std::string& msg, const Glsx::Exception& exc, int code): BASE(msg, exc, code)	\
// 	{																								\
// 	}																								\
// 	CLS::CLS(const CLS& exc): BASE(exc)																\
// 	{																								\
// 	}																								\
// 	CLS::~CLS() throw()																				\
// 	{																								\
// 	}																								\
// 	CLS& CLS::operator = (const CLS& exc)															\
// 	{																								\
// 		BASE::operator = (exc);																		\
// 		return *this;																				\
// 	}																								\
// 	const char* CLS::name() const throw()															\
// 	{																								\
// 		return NAME;																				\
// 	}																								\
// 	const char* CLS::className() const throw()														\
// 	{																								\
// 		return typeid(*this).name();																\
// 	}																								\
// 	Glsx::Exception* CLS::clone() const																\
// 	{																								\
// 		return new CLS(*this);																		\
// 	}																								\
// 	void CLS::rethrow() const																		\
// 	{																								\
// 		throw *this;																				\
// 	}
// 
// 
// //
// // Standard exception classes
// //
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, LogicException, Exception)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, AssertionViolationException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, NullPointerException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, NullValueException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, BugcheckException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, InvalidArgumentException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, NotImplementedException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, RangeException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, IllegalStateException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, InvalidAccessException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, SignalException, LogicException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, UnhandledException, LogicException)
// 
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, RuntimeException, Exception)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, NotFoundException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, ExistsException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, TimeoutException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, SystemException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, RegularExpressionException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, LibraryLoadException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, LibraryAlreadyLoadedException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, NoThreadAvailableException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, PropertyNotSupportedException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, PoolOverflowException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, NoPermissionException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, OutOfMemoryException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, DataException, RuntimeException)
// 
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, DataFormatException, DataException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, SyntaxException, DataException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, CircularReferenceException, DataException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, PathSyntaxException, SyntaxException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, IOException, RuntimeException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, ProtocolException, IOException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, FileException, IOException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, FileExistsException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, FileNotFoundException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, PathNotFoundException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, FileReadOnlyException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, FileAccessDeniedException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, CreateFileException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, OpenFileException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, WriteFileException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, ReadFileException, FileException)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, UnknownURISchemeException, RuntimeException)
// 
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, ApplicationException, Exception)
// GLSX_DECLARE_EXCEPTION(GlsxCommon_API, BadCastException, RuntimeException)


END_GLSX_NAMESPACE


#endif // Foundation_Exception_INCLUDED
